<template>
  <!-- 回复窗口 -->
  <Dialog ref="commentsDialog"
          :title="'您正在回复：' + nickname"
          @close="replyCommentsDialogVisible"
          @confirm="setCommentsRef"
          submit-text="回复"
  >
    <ReplyComments ref="replyCommentsRef"
                   :site-id="props.siteId"
                   placeholder="请输入回复内容"
                   :show-submit="false"
                   @commentAfter="commentAfter"
                   @commentBefore="commentBefore"
    />
  </Dialog>
  <!-- 评论循环体 -->
  <div class="comments" v-for="(item, index) in data" :key="index" :id="'comments-' + item.id">
    <div class="comments-avatar">
      <nuxt-link :to="'/user/' + item.userId" target="_blank">
        <Avatar :size="50" :src="item.avatar" :alt="item.nickName || item.createBy" :font-size="20">
          {{ (item.nickName || item.createBy).charAt(0) }}
        </Avatar>
      </nuxt-link>
    </div>
    <div class="comments-info">
      <div class="comments-name fs-14">
        <nuxt-link :to="'/user/' + item.userId">{{ item.nickName || item.createBy }}</nuxt-link>
        <el-tooltip effect="dark" :content="item.createTime" placement="top">
          <span class="comments-time pointer fs-12 f-gray-color">{{ item.createTime }}</span>
        </el-tooltip>
      </div>
      <div @click="props.isScrollIntoView ? jumpToUrl('/site/' + item.siteId + '?id=comments-' + item.id) : null"
           :class="'comments-content fs-14 ' + (props.isScrollIntoView ? 'pointer':null)"
      >
        {{ item.commentsText }}
      </div>
      <div class="comments-info fs-12 f-gray-color">
        <span>地点：{{ item.commentsIpAddress }}</span>
        <span>系统：{{ item.commentsSystem }}</span>
        <span>浏览器：{{ item.commentsBrowser }}</span>
      </div>
      <div class="comments-handle">
        <div v-if="checkUserNotUseOneself(item.createBy)">
          <el-button size="small" @click="setReplyComments(item)" link>回复</el-button>
        </div>
        <div v-if="checkUserUseOneself(item.createBy)">
          <el-popconfirm
              @confirm="delComments(item.id)"
              title="确定删除当前评论吗？"
              :icon="WarningFilled"
              icon-color="red"
              confirm-button-text="确定"
              cancel-button-text="取消"
              width="200"
          >
            <template #reference>
              <el-button type="danger" size="small" link>删除</el-button>
            </template>
          </el-popconfirm>
        </div>
      </div>
      <!-- 下级评论 -->
      <Card :is-header="false" v-if="item.children.length > 0" padding="0 10px 15px" margin="10px 0 0" shadow="never">
        <div class="comments"
             v-for="(child, childIndex) in item.children"
             :key="childIndex"
             :id="'comments-' + child.id"
        >
          <div class="comments-avatar">
            <nuxt-link :to="'/user/' + child.userId" target="_blank">
              <Avatar :size="50" :src="child.avatar" :alt="child.nickName || child.createBy" :font-size="20">
                {{ (child.nickName || child.createBy).charAt(0) }}
              </Avatar>
            </nuxt-link>
          </div>
          <div class="comments-info">
            <div class="comments-name fs-14">
              <nuxt-link :to="'/user/' + child.userId">{{ child.nickName || child.createBy }}</nuxt-link>
              <span class="f-gray-color">回复</span>
              <nuxt-link :to="'/user/' + child.repliedId">{{
                  child.repliedNickName || child.repliedUsername
                }}
              </nuxt-link>
              <el-tooltip effect="dark" :content="child.createTime" placement="top">
                <span class="comments-time pointer fs-12 f-gray-color">{{ child.createTime }}</span>
              </el-tooltip>
            </div>
            <div
                @click="props.isScrollIntoView ? jumpToUrl('/site/' + child.siteId + '?id=comments-' + child.id) : null"
                :class="'comments-content fs-14 ' + (props.isScrollIntoView ? 'pointer':null)"
            >
              {{ child.commentsText }}
            </div>
            <div class="comments-info fs-12 f-gray-color">
              <span>地点：{{ child.commentsIpAddress }}</span>
              <span>系统：{{ child.commentsSystem }}</span>
              <span>浏览器：{{ child.commentsBrowser }}</span>
            </div>
            <div class="comments-handle">
              <div v-if="checkUserNotUseOneself(child.createBy)">
                <el-button size="small" @click="setReplyComments(item, child)" link>回复</el-button>
              </div>
              <div v-if="checkUserUseOneself(child.createBy)">
                <el-popconfirm
                    @confirm="delComments(child.id)"
                    title="确定删除当前评论吗？"
                    :icon="WarningFilled"
                    icon-color="red"
                    confirm-button-text="确定"
                    cancel-button-text="取消"
                    width="200"
                >
                  <template #reference>
                    <el-button type="danger" size="small" link>删除</el-button>
                  </template>
                </el-popconfirm>
              </div>
            </div>
          </div>
        </div>
        <el-pagination
            v-if="props.isPage && item.childrenTotal > 0"
            small
            background
            layout="prev, pager, next"
            :total="item.childrenTotal"
            class="pagination"
            :page-size="getChildrenPageSize(item.id)"
            :pager-count="5"
            @size-change="(val: number) => {
              handleChildrenSizeChange(val, item.id);
            }"
            @current-change="(val: number) => {
              handleChildrenCurrentChange(val, item.id);
            }"
        />
      </Card>
    </div>
  </div>
  <el-pagination
      v-if="props.isPage && total > 0"
      small
      background
      layout="prev, pager, next"
      :total="Number(total)"
      class="pagination"
      :page-size="props.size"
      :pager-count="5"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
  />
  <Empty v-if="total < 1"/>
</template>

<script setup lang="ts">
import {WarningFilled} from "@element-plus/icons-vue";
import {Response} from "@/entity/response";
import {Comments} from "~/entity/comments";
import ReplyComments from "@/components/Comments/replyComments.vue";

const props = defineProps({
  siteId: {
    type: String,
    default: ""
  },
  username: {
    type: String,
    default: ""
  },
  size: {
    type: Number,
    default: 5
  },
  isPage: {
    type: Boolean,
    default: true
  },
  // 是否开启评论定位滚动
  isScrollIntoView: {
    type: Boolean,
    default: false
  }
});
const comments = ref<Comments>({
  siteId: props.siteId,
  createBy: props.username,
  childrenPageNum: 1,
  childrenPageSize: props.size
});
const data = ref<Comments[]>([]);
const total = ref<number>(0);
const pageSize = ref(props.size);
const pageNum = ref(1);
const childrenPageSize = reactive<any>([]);
const childrenPageNum = reactive<any>([]);
const {commentsApi} = useApi();
const nickname = ref("");
const username = ref("");
const commentsId = ref("");
const replyCommentsRef = ref();
const {loginStatus, userInfo} = useStoreToRefs(useStores.user());
const commentsDialog = ref();
const router = useRouter();
const route = useRoute();
onBeforeMount(() => {
  getComments();
});
watch(
    () => userInfo.value.avatar,
    () => {
      getComments();
    }
);
onMounted(() => {
  if (route.query.id && props.isScrollIntoView) {
    setTimeout(() => {
      const commentsElement = document.querySelector("#" + route.query.id);
      if (commentsElement) {
        commentsElement.scrollIntoView();
      }
    }, 500);
  }
});
const jumpToUrl = (url: string) => {
  router.push(url);
}
const setCommentsRef = () => {
  replyCommentsRef.value.commentsFormSubmit(replyCommentsRef.value.commentsFromRef);
};
const commentAfter = () => {
  getComments();
};
const commentBefore = (val: boolean) => {
  if (!val) {
    commentsDialog.value.dialogVisible = true;
  }
};
const getComments = () => {
  commentsApi.getList({
    pageSize: pageSize.value,
    pageNum: pageNum.value
  }, {
    ...comments.value
  }).then((res: any) => {
    const {rows, total: sum}: Response = res;
    data.value = rows || [];
    total.value = sum || 0;
    data.value.forEach((item: Comments) => {
      childrenPageSize.push({
        commentsId: item.id,
        pageSize: 5
      });
      childrenPageNum.push({
        commentsId: item.id,
        pageNum: 1
      });
    });
  });
};
const delComments = (id: string) => {
  commentsApi.delComments(id).then((res: any) => {
    const {data}: Response = res;
    if (data) {
      useUtils().ModalUtils.msgSuccess("删除成功");
      getComments();
    }
  });
}
const replyCommentsDialogVisible = () => {
  username.value = "";
  nickname.value = "";
  commentsId.value = "";
}
const setReplyComments = (comments: Comments, commentsChild?: Comments) => {
  if (commentsChild) {
    username.value = commentsChild.createBy || "";
    nickname.value = commentsChild.nickName || commentsChild.createBy || "";
  } else {
    username.value = comments.createBy || "";
    nickname.value = comments.nickName || comments.createBy || "";
  }
  commentsId.value = comments.id || "";
  commentsDialog.value.dialogVisible = true;
  // 使用 setTimeout 是为了解决 updateRepliedUserName is undefined
  setTimeout(() => {
    replyCommentsRef.value.updateRepliedUserName(username.value);
    replyCommentsRef.value.updateCommentsId(commentsId.value);
  }, 1);
}
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  getComments();
}
const handleCurrentChange = (val: number) => {
  pageNum.value = val;
  getComments();
}
const handleChildrenSizeChange = (val: number, id: string) => {
  const pageSize = childrenPageSize.find((item: any) => item.commentsId == id);
  childrenPageNum.forEach((item: any) => {
    if (item.id == id) {
      item.pageNum = val;
      throw new Error("更新子评论页码");
    }
  });
  getChildrenComments(id, pageSize.pageSize, val);
}
const handleChildrenCurrentChange = (val: number, id: string) => {
  const pageSize = childrenPageSize.find((item: any) => item.commentsId == id);
  childrenPageNum.forEach((item: any) => {
    if (item.id == id) {
      item.pageNum = val;
      throw new Error("更新子评论页码");
    }
  });
  getChildrenComments(id, pageSize.pageSize, val);
}
const getChildrenComments = (id: string, size: number, num: number) => {
  commentsApi.getChildrenList(id, {
    pageSize: size,
    pageNum: num
  }).then((res: any) => {
    const {rows, total: sum}: Response = res;
    data.value.forEach((item: Comments) => {
      if (item.id == id) {
        item.children = rows || [];
        throw new Error("更新子评论列表");
      }
    });
  });
}
const getChildrenPageSize = (id: string) => {
  const children = childrenPageSize.find((child: any) => child.commentsId == id);
  return children?.pageSize ? children?.pageSize : 0;
};
const checkUserNotUseOneself = (username: string) => {
  return loginStatus.value && userInfo.value.userName != username;
}
const checkUserUseOneself = (username: string) => {
  return loginStatus.value && userInfo.value.userName == username;
}
defineExpose({
  getComments
});
</script>

<style scoped lang="scss">
.comments {
  display: flex;
  margin-top: 15px;

  .comments-avatar {
    margin-right: 10px;
  }

  .comments-info {
    width: 100%;
    line-height: 25px;

    .comments-name {
      .comments-time {
        margin-left: 5px;
      }
    }

    .comments-info {
      span {
        margin-right: 5px;
      }
    }

    .comments-handle {
      display: flex;

      div {
        margin-right: 5px;
      }
    }
  }
}

.pagination {
  margin-top: 10px;
  justify-content: center;
}

::v-deep(.el-button--small) {
  padding: 0;
}
</style>